package com.biqee.service.tb.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

import com.biqee.constant.TBConstant;
import com.biqee.exception.AccessBlockException;
import com.biqee.exception.BusinessUnCheckedException;
import com.biqee.exception.ErrorCode;
import com.biqee.model.TaobaoParseReulst;
import com.biqee.model.TbQueryModel;
import com.biqee.model.common.PageInfoObject;
import com.biqee.model.db.TbItem;
import com.biqee.service.bq.BqQueryRelationService;
import com.biqee.service.crawler.PageFetcher;
import com.biqee.service.tb.TbQueryListParser;
import com.biqee.service.tb.TbsearchService;
import com.biqee.util.JsoupUtil;
import com.biqee.util.NumberUtil;
import com.biqee.util.SegmentUtil;
import com.biqee.util.StoreUtil;
import com.biqee.util.StringUtil;
import com.biqee.util.TaobaoAccessUtil;

public class TbsearchServiceImpl implements TbsearchService {
	private static final int MAX_SEARCH_SIZE = 80;
	private static final String TB_ENCODE = TBConstant.TB_DEFALT_CHARTSET;
	private static final Logger logger = Logger
			.getLogger(TaobaoCShopParseServiceImpl.class);

	private PageFetcher pageFetcher;

	private TbQueryListParser tbQueryListParser;

	private BqQueryRelationService bqQueryRelationService;

	public int search(TbQueryModel query) {
		return search(query, false);
	}

	public int search(final TbQueryModel query, boolean cacheEnable) {
		String q = query.getBqQuery().getQueryQ();
		if (StringUtil.isBlank(q)) {
			throw new BusinessUnCheckedException(ErrorCode.BIZ_TUAN_002);
		}
		
		// 注意不要捕获并丢弃 AccessBlockedException
		String html = getHtml(query, cacheEnable);
		PageInfoObject page = query.getPageInfoObject();
		initPage(page, html);
		bqQueryRelationService.clearRelationByQueryId(query.getBqQuery()
				.getId());
		if (page.getCount() < 2) {
			//缩小关键字范围
			 q = SegmentUtil.splitSmart(q);
			 if (!StringUtil.isBlank(q)) {
			 query.getBqQuery().setQueryQ(q);
			 
			 // 注意不要捕获并丢弃 AccessBlockedException
			 html = getHtml(query, cacheEnable);
			 initPage(page, html);
			 if(page.getCount()==0){
				 return  0 ;
			 }
			 logger.warn("tuanId="+query.getBqQuery().getTuanId()+"reseach by new q="+q);
		
			 }
		}

		List<TaobaoParseReulst> list = null;
		for (int i = 0; i < page.getPageCount(); i++) {
			if (i != 0) {
				// 注意不要捕获并丢弃 AccessBlockedException
				html = getHtml(query, cacheEnable);
			}
			
			list = tbQueryListParser.parseHtml(html);
			if (list != null && !list.isEmpty()) {
				List<TbItem> items = getTbItems(list);
				bqQueryRelationService
						.createRelation(query.getBqQuery(), items);
			}
			page.turnNextPage();
		}

		return page.getCount();
	}

	private List<TbItem> getTbItems(List<TaobaoParseReulst> list) {
		List<TbItem> result = new ArrayList<TbItem>();
		if (list != null) {
			for (TaobaoParseReulst ps : list) {
				if (ps.getTbItem() != null) {
					result.add(ps.getTbItem());
				}
			}
		}
		return result;
	}

	public void initPage(PageInfoObject page, String html) {
		Document doc = JsoupUtil.createDocument(html);
		Elements countElments = doc.select("div.result-count em");
		if (countElments != null && !countElments.isEmpty()) {
			String count = countElments.first().text();
			page.setCount(NumberUtil.toInt(count));

		} else {
			page.setCount(0);
			logger.error("data parse error: count not find");
		}

		if (page.getCount() > MAX_SEARCH_SIZE) {
			page.setCount(MAX_SEARCH_SIZE);
		}
	}

	private String getHtml(TbQueryModel query, boolean cacheEnable) {
		String fileName = query.buildFileName();
		String relativePath = null;
		String html = null;

		
		if (cacheEnable) {
			relativePath = StoreUtil.createRelativeFilePath(fileName);
			try {
				html = StoreUtil.readFile(relativePath, TB_ENCODE);
			} catch (IOException e) {
				logger.error(e.getMessage());
			}
		}
		
		if (html == null) {
			String url = query.buildQueryUrl();
			logger.info("search url: " + url);
			html = pageFetcher.getAsStringWithSpiderHeader(url, TB_ENCODE);

			
			if(TaobaoAccessUtil.isBlocked(html)) {
				throw new AccessBlockException("taobao block us!");
			}
			
			logger.info("store list file=" + relativePath);

			try {
				if (cacheEnable) {
				StoreUtil.storeFile(relativePath, html,
						TBConstant.TB_DEFALT_CHARTSET);
				logger.info("store list file=" + relativePath);
				}
			} catch (IOException e) {
				logger.error(e.getMessage());
			}
		}
		
		return html;
	}

	public void setPageFetcher(PageFetcher pageFetcher) {
		this.pageFetcher = pageFetcher;
	}

	public void setTbQueryListParser(TbQueryListParser tbQueryListParser) {
		this.tbQueryListParser = tbQueryListParser;
	}

	public void setBqQueryRelationService(
			BqQueryRelationService bqQueryRelationService) {
		this.bqQueryRelationService = bqQueryRelationService;
	}

}
